home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Toolbox
/
Visual Basic Toolbox (P.I.E.)(1996).ISO
/
graphics
/
resnc
/
resnc.txt
Wrap
Text File
|
1995-04-30
|
8KB
|
188 lines
Ok guys/gals, here it is. Basically, I'm going to show how I implemented a resource-only
dll to hold bitmaps. Then I'll talk about how to retrieve them, get their color tables,
and basically how to use them once their alive and living in your RAM. Um, also I'll talk
about a technique I learned about from Mark Novisoff, founder of Microhelp in Georgia(you
know Unistaller and all that), where you can store any files in one single file for a
resource depository. The reason for this is two-fold 1) one of you asked about storing
AVI's and WAV's instead of bmp's and 2) it's VB specific and the API ()'s to retrieve bmp's
from true a dll can not store WAV's and AVI's.
So, off we go:
\ /
:-)===00
/ \.
PHASE I: Creating the DLL___________________________________________________________________
This is the your source file.
%%%%%%%%%%%%%%%%%MyResOnlyDll.C%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//Resource only dll
#include <windows.h>
//Declare the Windows-callable WindowsExitProcedure()
int FAR PASCAL _export WEP (int nParam);
//This is the DLL's entry point, in the eye's of Windows
int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg,
WORD wHeapSize, LPSTR lpszCmdLine)
{
if (wHeapSize > 0)
UnlockData(0); //This unlock's the dll's data segment
//and is required
return 1; //Then it returns 1 to Windows, saying all is well
}
//This is called by Windows when the dll's refernce count is = 0
//or more simply when the dll is unloaded by you. If you want to
//know about reference count's read about it in the SDK, it's somewhere
//in there :)
int FAR PASCAL _export WEP (int nParam)
{
return 1; //Just return 1 and Windows handles the rest
}
//Oh yea, get used to the reference count methodology, it is how
//OLE manages the lifespan of an object too.
Ok, this code gives you all you need for the main dll body code. It
provided a way for Windows to say hello, do initialization if you need to, and then
a way to say goodbye, do de-initialization if you need to.
%%%%%%%%%%%%%%%%%%%%End of MyResOnlyDll.C%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Then you need a module definition file. And here's the skeleton code for it.
%%%%%%%%%%%%%%%%%%%%MyResOnlyDll.def%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//Resource only DLL
LIBRARY MODNAME //Name your module
DESCRIPTION 'Put a description here for your module'
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
%%%%%%%%%%%%%%%%%%%%End of MyResOnlyDll.def%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Ok, we've got the main dll body code done, the module's definition defined and now here's
how to #include your bitmap's.
%%%%%%%%%%%%%%%%%%%%MyResOnlyDll.rc%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1 BITMAP bitmap1.bmp //Or use a full path 'c:\\graphics\\bmps\\bitmap1.bmp'
2 BITMAP bitmap2.bmp
%%%%%%%%%%%%%%%%%%%%End MyResOnlyDll.rc%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Now build your dll. That's it. You've given your Visual C compiler all the necessary info
to turn your bitmaps into one resource file.
PHASE II: Retrieving bitmaps in 256 colors from our DLL___________________________________
Now you've got a dll to load into memory and extract image's from. The following is an
excerpt from some C code I wrote to load an image from my dll.
if ((hLib = LoadLibrary("dllres.dll")) < 32)
{
DestroyWindow(hwnd);
return 0;
}
//Load DIBmp from dll
hRes = FindResource(hLib, MAKEINTRESOURCE(2), RT_BITMAP);
hGlobal = LoadResource(hLib, hRes);
lpbmi = (LPBITMAPINFOHEADER)LockResource(hGlobal);
//Create palette from dib
hPal = CreateDIBPalette(lpbmi);
hdc = GetDC(hwnd);
SelectPalette(hdc, hPal, FALSE);
RealizePalette(hdc);
//check for non zero clrused member
if (lpbmi->biClrUsed)
iNumColors = (WORD)lpbmi->biClrUsed;
else
iNumColors = 256;
hMyBmp = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)lpbmi,
(LONG)CBM_INIT,
(LPSTR)lpbmi + lpbmi->biSize + iNumColors *
sizeof(RGBQUAD),
(LPBITMAPINFO)lpbmi,
DIB_RGB_COLORS);
ReleaseDC(hwnd, hdc);
UnlockResource(hGlobal);
FreeResource(hGlobal);
Starting from the top, here we go. Basically, the only useful bitmaps these days are
8bit or 256 color bitmaps. So, the previous code compensates for this. It does this by
getting a pointer to the bitmap data in memory. The FindRes, LoadRes and LockRes API calls
are the sequence of calls that do this. In the FindRes, the RT_BITMAP parameter tells
Windows were loading a bitmap from this dll, so it knows how to extract the bitmap. Now, we've
got a pointer to bitmap in memory. We can then 'walk' to its color table to create a palette
compatible with bitmap. Without, getting too far ahead of myself here's the code for creating
this palette from my 8bit bitmap. It could be adjusted simply to compensate for 16 bit and 24
bit bitmaps.
HPALETTE CreateDIBPalette(LPBITMAPINFOHEADER lpbmi)
{
LPBITMAPINFO lpbi;
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal = NULL;
int i, iColors;
lpbi = (LPBITMAPINFO)lpbmi; //convert to struct that has color info
if (lpbmi->biClrUsed) //check the # of colors used by your bmp's
iColors = (WORD)lpbmi->biClrUsed;
else
iColors = 256;
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * iColors);
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
lpPal->palVersion = 0x300;
lpPal->palNumEntries = iColors;
for (i = 0; i < iColors; i++)
{
lpPal->palPalEntry[i].peRed = lpbi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = lpbi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = lpbi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
hPal = CreatePalette(lpPal);
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return hPal;
}
So, we get a long pointer to a bitmapinfoheader structure for our bitmap. I check the structure
for the number of colors actually used by the bitmap. This isn't always 256 for an 8 bit bmp.
It could be anything <= 256. Once I got that, I then allocate enough memory to hold a palette
of this resolution in memory. I then GlobalLock it to get a pointer to this memory. Now, I can
start initializing this memory. The lpPal->palVersion = hex 300 is required. Then, I read
from the bitmap's structure, its color information into the logical palette. Once,
I've filled the logical palette with color values I call CreatePalette to actually get a handle
to the palette for future API calls. Then Unlock and Free the logical palette and return to
the caller the handle to this particular DIB's palette.
Now, if you look at the code from above we can then use this palette to set up a memDC in which
we select this palette and then call CreateDIBitmap to actually create a ***device dependent
bitmap****. Once you have a DDB, you then BitBlt to the screen or whatever you want.
The bitmaps included in this zip file show how to create an indexed file to hold any type of
information. In the example, the author shows how to fill the file with bitmaps, but you
could put .AVI's or .WAV's in there.
So, I hope all this was useful, I would have liked to put in a .hlp format but I just don't
have the time. Anyway, I hope this helps. Sorry it took so darn long.
Chris Douglass
Imagesoft